package server

import (
	"ChatServerDemo/protocol"
	"ChatServerDemo/server/gm"
	"ChatServerDemo/server/user"
	"ChatServerDemo/server/utils"
	"encoding/json"
	"net"
	"strconv"
	"strings"
	"time"
)

type Channel struct {
	Name	string
	UserMap map[string]*user.User
	ChatMsg []string
	Popular map[string][]int64
	ticker *time.Ticker
}

func NewChannel(name string) *Channel {
	local := &Channel{Name:name, UserMap:make(map[string]*user.User), ChatMsg:[]string{}, Popular:make(map[string][]int64),ticker:time.NewTicker(1 * time.Second)}
	go local.Interval(local.ticker.C)
	return local
}

func (slf *Channel) Interval(c <-chan time.Time) {
	for range c {
		// do something
		//utils.Log("%s Interval %s", time.Now(), slf.Name)

		var delKey []string
		delKey = []string{}
		now := time.Now().Unix()
		for k,v := range slf.Popular {
			if len(v) == 2 {
				t := now - v[0]
				if t >= 60 {
					delKey = append(delKey, k)
				}
			}
		}
		for i:=0;i<len(delKey);i++{
			delete(slf.Popular, delKey[i])
		}
	}
}

func (slf *Channel) Join(conn net.Conn, s string) bool {

	_, exist := slf.UserMap[s]
	if exist {
		utils.Log("[%s] already exist Join fail", s)
		return false
	}else {
		slf.UserMap[s] = user.NewUser(conn, s)
		utils.Log("[%s] Join %s", s, slf.Name)
		slf.UserMap[s].SendClientMsgAll(slf.ChatMsg)
		return true
	}
}

func (slf *Channel) SendMsg(msg string) {

	packet := protocol.SendMsg{}
	err := json.Unmarshal([]byte(msg), &packet)
	if err != nil {
		utils.Log("UnKownPack[%s] err:%+v", string(msg), err)
		return
	}

	if strings.HasPrefix(packet.Msg, "./") {
		cmd := gm.Parser(strings.ReplaceAll(packet.Msg, "./", ""))
		msg := ""
		if cmd[0] == "stats" && len(cmd) >= 2{
			msg = gm.ExecStats(slf.UserMap, cmd[0], cmd[1])

		}else if cmd[0] == "popular" && len(cmd) >= 2 {
			t, _ := strconv.ParseInt(cmd[1], 10, 64)
			msg = gm.ExecPopular(slf.Popular, cmd[0], t)

		}

		m := protocol.ReceiveMsg{
			Nick:      packet.Nick,
			Msg:      msg,
			Timestamp: time.Now().Unix(),
		}


		u, exist := slf.UserMap[packet.Nick]
		if exist {
			u.SendClient("ReceiveMsg", m)
		}

	}else{

		txt := slf.checkMsg(packet.Msg)
		m := protocol.ReceiveMsg{
			Nick:      packet.Nick,
			Msg:      txt,
			Timestamp: time.Now().Unix(),
		}

		jsonMsg, _ := json.Marshal(m)

		slf.ChatMsg = append(slf.ChatMsg, string(jsonMsg))
		slf.checkLength()

		slf.Broadcast(m)
	}
}

func (slf *Channel) Kick(s string) {

	u, exist := slf.UserMap[s]
	if exist {
		u.Kick()
		delete(slf.UserMap, s)
		utils.Log("Kick [%s] From %s", s, slf.Name)
	}
}

func (slf *Channel) Broadcast(msg protocol.ReceiveMsg) {

	for _,v :=range slf.UserMap {
		v.SendClient("ReceiveMsg", msg)
	}
}

func (slf *Channel) checkLength() {
	length := len(slf.ChatMsg)
	if length > 50 {
		slf.ChatMsg = slf.ChatMsg[length-50:length]
	}
}

//缓存流行词汇 检测屏蔽词
func (slf *Channel) checkMsg(msg string) string {
	m := strings.Split(msg, " ")
	for _,v := range m {
		s, exist := slf.Popular[v]
		if exist {
			s[0] = time.Now().Unix()
			s[1] = s[1]+1
			slf.Popular[v] = s
		} else {
			slf.Popular[v] = []int64{time.Now().Unix(), 1}
		}
	}
	return utils.CheckInvalidWord(msg)
}